import numpy as np
import cv2


def crop_image(image, region):
    y_start, y_end, x_start, x_end = region
    
    if y_start < 0 or y_end > image.shape[0] or x_start < 0 or x_end > image.shape[1]:
        print("裁剪区域超出图像范围")
        return None
    
    return image[y_start:y_end, x_start:x_end]


def adjust_brightness(image, factor):
    factor = max(0.0, factor)
    
    if len(image.shape) == 3:
        return np.clip(image * factor, 0, 255).astype(image.dtype)
    else:
        return np.clip(image * factor, 0, 255).astype(image.dtype)


def global_threshold(image, threshold):
    return np.where(image > threshold, 255, 0).astype(image.dtype)


def move_difference(image, shift):
    shifted = np.roll(image, shift, axis=1)
    diff = np.abs(image.astype(np.int32) - shifted.astype(np.int32))
    return np.clip(diff, 0, 255).astype(image.dtype)


def create_channel_mask(image, channel):
    if channel == 'red':
        channel_data = image[:, :, 0]
    elif channel == 'green':
        channel_data = image[:, :, 1]
    elif channel == 'blue':
        channel_data = image[:, :, 2]
    else:
        raise ValueError("不支持的通道类型")
    
    threshold = 128
    return (channel_data > threshold).astype(np.uint8)


def apply_bitwise_operation(image, mask, operation):
    if operation == 'and':
        return cv2.bitwise_and(image, image, mask=mask)
    elif operation == 'or':
        return cv2.bitwise_or(image, image, mask=mask)
    elif operation == 'not':
        return cv2.bitwise_not(image, image, mask=mask)
    elif operation == 'xor':
        return cv2.bitwise_xor(image, image, mask=mask)
    else:
        raise ValueError("不支持的位运算类型")


def invert_colors(image):
    """
    反色处理
    :param image: 输入图像
    :return: 反色后的图像
    """
    return 255 - image


def otsu_threshold(image):
    _, thresholded = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    return thresholded


def sobel_edge(image):
    sobelx = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
    sobely = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
    
    magnitude = np.sqrt(sobelx**2 + sobely**2)
    magnitude = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
    
    return magnitude


def create_custom_mask(image, lower, upper):
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    return (mask > 0).astype(np.uint8)